package com.naiterui.ehp.bp.support.advice;

import cn.hutool.core.collection.CollectionUtil;
import java.lang.reflect.Method;
import java.util.List;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.google.common.collect.Lists;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.bp.support.security.HeaderConstant;
import com.naiterui.ehp.bp.support.utils.JsonMapper;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@ControllerAdvice("com.naiterui")
public class ResponseEntityAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
        Method method = returnType.getMethod();
        if (method == null || method.isAnnotationPresent(IgnoreResponseEntityWrap.class)) {
            return false;
        }
        return !ResponseEntity.class.equals(method.getReturnType());
    }

    @Override
    public Object beforeBodyWrite(Object body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType,
                                  @NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NonNull ServerHttpRequest request,
                                  @NonNull ServerHttpResponse response) {

        if (body instanceof String) {
            return JsonMapper.toJson(PublicService.returnResponseVO(body));
        }
        //2020/5/13 10:55 上午 王泽浩 这里要判断是不是需要包装data
        //String ip = IpUtil.getIp(RequestHolder.getHttpServletRequest());
        //if (NetUtil.isInnerIP(ip)) {
        //    if (body instanceof ResponseVO) {
        //        return body;
        //    } else {
        //        return PublicService.returnResponseVO(body);
        //    }
        //}

        if (body instanceof ResponseVO) {
            ResponseVO<Object> responseVO = (ResponseVO) body;
            Object data = responseVO.getData();
            if (this.isWrapData(request)) {
                if (!(data instanceof List)) {
                    responseVO.setData(Lists.newArrayList(data));
                }
            }
            return responseVO;
        }
        if (this.isWrapData(request)) {
            if (!(body instanceof List)) {
                return PublicService.returnResponseVO(Lists.newArrayList(body));
            }
        }
        return PublicService.returnResponseVO(body);
    }

    /**
     * 判断是前端是否需要包装data为list
     */
    private boolean isWrapData(ServerHttpRequest request) {
        if (CollectionUtil.isNotEmpty(request.getHeaders().get(HeaderConstant.DATA_NO_WRAP))) {
            return false;
        }
        return CollectionUtil.isNotEmpty(request.getHeaders().get(HeaderConstant.HEADER_PLATFORM));
    }

}
